package com.mebs.model;

import javax.persistence.*;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Company
 */
@Entity()
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "COMPANY")
@PrimaryKeyJoinColumn(name = "CompanyId")
public class Company extends Occupier {

    public static final String NAME_MEBS = "MEBS";

    @Column(name = "Name", length = 250, nullable = false, unique = true)
    private String name;

    @Column(name = "Ticker", length = 10, nullable = false, unique = true)
    private String ticker;

    @Column(name = "Email", length = 250)
    private String email;

    @Column(name = "WebSite", length = 250)
    private String webSite;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "CompanyId")
    @OrderBy("lastName,middleName,firstName")
    private Set<User> users;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "CompanyId")
    @OrderBy("name")
    private Set<Project> projects;

    @Column(name = "ConfirmationSequence")
    private Integer confirmationSequence;

    @Column(name = "RelocationOrderSequence")
    private Integer relocationOrderSequence;

    @Column(name = "LogisticsSequence")
    private Integer logisticsSequence;

    @Column(name = "ServiceSequence")
    private Integer serviceSequence;

    @Column(name = "POAReceived", nullable = true)
    private Boolean POAReceived;

    @Column(name = "KnownShipper", nullable = true)
    private Boolean knownShipper;

    @Column(name = "billingData", nullable = true)
    private Boolean BillingData;

    @Column(name = "Notes", nullable = true, length = 1024)
    private String notes;

    @Column(name = "ContactName", nullable = true, length = 250)
    private String contactName;

    public Company()
    {
        super();

        // default values
        this.setConfirmationSequence(0);
        this.setLogisticsSequence(0);
        this.setServiceSequence(0);
        this.setRelocationOrderSequence(0);
    }

    /**
     * ********************** Getters-setters ***********************
     */
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getTicker()
    {
        return ticker;
    }

    public void setTicker(String ticker)
    {
        if ((ticker != null) && (ticker.indexOf('-') > 0)) {
            // todo may be to throw an exception?
            ticker = Pattern.compile("-").matcher(ticker).replaceAll("");
        }
        this.ticker = ticker;
    }

    public String getEmail()
    {
        return email;
    }

    public void setEmail(String email)
    {
        this.email = email;
    }

    public String getWebSite()
    {
        return webSite;
    }

    public void setWebSite(String webSite)
    {
        this.webSite = webSite;
    }

    public Set<User> getUsers()
    {
        return users;
    }

    public void setUsers(Set<User> users)
    {
        this.users = users;
    }

    public Set<Project> getProjects()
    {
        return projects;
    }

    public void setProjects(Set<Project> projects)
    {
        this.projects = projects;
    }

    public Integer getConfirmationSequence()
    {
        return confirmationSequence;
    }

    private void setConfirmationSequence(Integer confirmationSequence)
    {
        this.confirmationSequence = confirmationSequence;
    }

    @Transient
    public Integer getIncrementedConfirmationSequence()
    {
        confirmationSequence++;
        return confirmationSequence;
    }

    public Integer getRelocationOrderSequence()
    {
        return relocationOrderSequence;
    }

    public void setRelocationOrderSequence(Integer relocationOrderSequence)
    {
        this.relocationOrderSequence = relocationOrderSequence;
    }

    @Transient
    public Integer getIncrementedRelocationOrderSequence()
    {
        relocationOrderSequence++;
        return relocationOrderSequence;
    }

    public Integer getLogisticsSequence()
    {
        return logisticsSequence;
    }

    public void setLogisticsSequence(Integer logisticsSequence)
    {
        this.logisticsSequence = logisticsSequence;
    }

    @Transient
    public Integer getIncrementedLogisticsSequence()
    {
		logisticsSequence++;
        return logisticsSequence;
    }

    public Integer getServiceSequence()
    {
        return serviceSequence;
    }

    public void setServiceSequence(Integer serviceSequence)
    {
        this.serviceSequence = serviceSequence;
    }

    public Boolean getPOAReceived()
    {
        return POAReceived;
    }

    public void setPOAReceived(Boolean POAReceived)
    {
        this.POAReceived = POAReceived;
    }

    public Boolean getKnownShipper()
    {
        return knownShipper;
    }

    public void setKnownShipper(Boolean knownShipper)
    {
        this.knownShipper = knownShipper;
    }

    public Boolean getBillingData()
    {
        return BillingData;
    }

    public void setBillingData(Boolean billingData)
    {
        BillingData = billingData;
    }

    public String getNotes()
    {
        return notes;
    }

    public void setNotes(String notes)
    {
        this.notes = notes;
    }

    public String getContactName()
    {
        return contactName;
    }

    public void setContactName(String contactName)
    {
        this.contactName = contactName;
    }

    @Transient
    public Integer getIncrementedServiceSequence()
    {
        serviceSequence++;
        return serviceSequence;
    }

    @Transient
    public Set<User> getNonDeletedUsers()
    {
        Set<User> res = new HashSet<User>();
        for (User user : this.users) if (! user.isDeleted()) res.add(user);
        return res;
    }

    @Override
    public String toString()
    {
        return this.name;
    }

}
